from os import name
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from typing import Optional, Dict, Any, List
from core.security import pwd_context
from core.token_manager import create_access_token, create_refresh_token, decode_token
from config.config import settings
from modules.system.services.dept_service import DeptService
from modules.system.models.user import User  # type: ignore
from modules.system.models.role import Role
from modules.system.models.user_role import UserRole
from utils.log_util import logger


class AuthService:
    @staticmethod
    async def authenticate(db: AsyncSession, username: str, password: str) -> Optional[Dict[str, Any]]:
        """用户认证"""
        q = select(User).where(User.username == username)
        res = await db.execute(q)
        user = res.scalar_one_or_none()
        if not user:
            return None
        # 假设数据库中的 password 存储为哈希
        if not pwd_context.verify(password, user.password):
            return None
        
        # 查询用户的角色信息（ID和名称）
        role_q = (select(Role.id, Role.name)
                 .join(UserRole, Role.id == UserRole.role_id)
                 .where(UserRole.user_id == user.id))
        role_res = await db.execute(role_q)
        roles_info = [{'id': row[0], 'name': row[1]} for row in role_res.all()]
        # 获取用户可访问的部门编码列表（包括子部门）
        dept_codes = await DeptService.get_dept_children_codes(db, user.department)

        return {
            "id": user.id,
            "username": user.username,
            "name": user.name,
            "roles": [role['name'] for role in roles_info],
            "role_ids": [role['id'] for role in roles_info],
            "department": user.department,
            "dept_codes": dept_codes,  # 将部门编码列表添加到返回结果中
        }

    @staticmethod
    async def issue_tokens(user_payload: Dict[str, Any]) -> Dict[str, str]:
        """签发 access 和 refresh 令牌"""
        access = create_access_token({  
            "sub": user_payload["username"], 
            "uid": user_payload["id"], 
            "name": user_payload["name"],
            "roles": user_payload.get("roles", []),
            "role_ids": user_payload.get("role_ids", []),
            "department": user_payload.get("department"),
            "dept_codes": user_payload.get("dept_codes", [])  # 添加 dept_codes 到 token 中
        })
        refresh = create_refresh_token({"sub": user_payload["username"], "uid": user_payload["id"]})
        return {"access_token": access, "refresh_token": refresh}

    @staticmethod
    async def refresh_tokens(refresh_token: str) -> Dict[str, str]:
        payload = decode_token(refresh_token)
        if payload.get("type") != "refresh":
            raise ValueError("无效的刷新令牌类型")
        user_data = {"username": payload.get("sub"), "id": payload.get("uid")}
        access = create_access_token({"sub": user_data["username"], "uid": user_data["id"]})
        new_refresh = create_refresh_token({"sub": user_data["username"], "uid": user_data["id"]})
        return {"access_token": access, "refresh_token": new_refresh}

    @staticmethod
    def hash_password(plain: str) -> str:
        """生成密码哈希，便于创建/迁移用户"""
        return pwd_context.hash(plain)

    @staticmethod
    async def get_user_by_id(db: AsyncSession, user_id: int) -> Optional[Dict[str, Any]]:
        """根据用户ID查询用户详情，返回字典结构"""
        res = await db.execute(select(User).where(User.id == user_id))
        user = res.scalar_one_or_none()
        if not user:
            return None

        roles = [r.name for r in getattr(user, "roles", [])] if hasattr(user, "roles") else []

        return {
            "id": getattr(user, "id", None),
            "username": getattr(user, "username", None),
            "name": getattr(user, "name", None),
            "avatar": getattr(user, "avatar", None),
            "email": getattr(user, "email", None),
            "phone": getattr(user, "phone", None),
            "department": department,
            "roles": roles,
        }